﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
namespace DataService.Office.Word
{
    public class XmlToImg
    {
        /// <summary>
        /// 插入图片,默认宽度和默认高度
        /// </summary>
        /// <param name="body"></param>
        /// <param name="relationshipId"></param>
        /// <param name="imgWidth">图片在word显示的宽度（单位：cm）,默认5.93cm</param>
        /// <param name="imgHeight">图片在word显示的高度（单位：cm），默认10.2cm</param>
        public static void AddImageToBody(DocumentFormat.OpenXml.Wordprocessing.Body body, string relationshipId, decimal imgWidth =(decimal)10.2, decimal imgHeight =(decimal)5.93)
        {
            //Open xml中的度量单位为EMU（全称为 English Metric Unit)，1cm =360000EMUS,所以7.935cm=7.935*360000=2857500
            //如 new DW.Extent() { Cx = 990000L, Cy = 792000L }，宽(cm)*高(cm)=(990000/360000)*(792000/360000)
            long cx = (long)(imgWidth * 360000);
            long yx = (long)(imgHeight * 360000);
            var element =
                 new Drawing(
                     new DW.Inline(
                         new DW.Extent() { Cx = cx, Cy = yx }, // 调节图片大小, new DW.Extent() { Cx = 990000L, Cy = 792000L }
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = "Picture1",
                             Title = "投标图片"
                         },
                         new DW.NonVisualGraphicFrameDrawingProperties(
                             new DocumentFormat.OpenXml.Drawing.GraphicFrameLocks() { NoChangeAspect = true }),
                         new DocumentFormat.OpenXml.Drawing.Graphic(
                             new DocumentFormat.OpenXml.Drawing.GraphicData(
                                 new PIC.Picture(
                                     new PIC.NonVisualPictureProperties(
                                         new PIC.NonVisualDrawingProperties()
                                         {
                                             Id = (UInt32Value)0U,
                                             Name = "New Bitmap Image.jpg"
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new DocumentFormat.OpenXml.Drawing.Blip(
                                             new DocumentFormat.OpenXml.Drawing.BlipExtensionList(
                                                 new DocumentFormat.OpenXml.Drawing.BlipExtension()
                                                 {
                                                     Uri =
                                                       "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 })
                                         )
                                         {
                                             Embed = relationshipId,
                                             CompressionState =
                                             DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print
                                         },
                                         new DocumentFormat.OpenXml.Drawing.Stretch(
                                             new DocumentFormat.OpenXml.Drawing.FillRectangle())),
                                     new PIC.ShapeProperties(
                                         new DocumentFormat.OpenXml.Drawing.Transform2D(
                                             new DocumentFormat.OpenXml.Drawing.Offset() { X = 0L, Y = 0L },
                                             new DocumentFormat.OpenXml.Drawing.Extents() { Cx = cx, Cy = yx }), //与上面的对准
                                         new DocumentFormat.OpenXml.Drawing.PresetGeometry(
                                             new DocumentFormat.OpenXml.Drawing.AdjustValueList()
                                         )
                                         { Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle }))
                             )
                             { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                     )
                     {
                         DistanceFromTop = (UInt32Value)0U,
                         DistanceFromBottom = (UInt32Value)0U,
                         DistanceFromLeft = (UInt32Value)0U,
                         DistanceFromRight = (UInt32Value)0U,
                         EditId = "50D07946"
                     });
            // Append the reference to body, the element should be in a Run.
            body.AppendChild(new Paragraph(new Run(element)));
        }



        public static void AddImageToParagraph(Paragraph paragraph, string relationshipId, decimal imgWidth, decimal imgHeight)
        {
            //Open xml中的度量单位为EMU（全称为 English Metric Unit)，1cm =360000EMUS,所以7.935cm=7.935*360000=2857500
            //如 new DW.Extent() { Cx = 990000L, Cy = 792000L }，宽(cm)*高(cm)=(990000/360000)*(792000/360000)
            long cx = (long)(imgWidth * 360000);
            long yx = (long)(imgHeight * 360000);
            var element =
                 new Drawing(
                     new DW.Inline(
                         new DW.Extent() { Cx = cx, Cy = yx }, // 调节图片大小, new DW.Extent() { Cx = 990000L, Cy = 792000L }
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = "Picture1",
                             Title = "投标图片"
                         },
                         new DW.NonVisualGraphicFrameDrawingProperties(
                             new DocumentFormat.OpenXml.Drawing.GraphicFrameLocks() { NoChangeAspect = true }),
                         new DocumentFormat.OpenXml.Drawing.Graphic(
                             new DocumentFormat.OpenXml.Drawing.GraphicData(
                                 new PIC.Picture(
                                     new PIC.NonVisualPictureProperties(
                                         new PIC.NonVisualDrawingProperties()
                                         {
                                             Id = (UInt32Value)0U,
                                             Name = "New Bitmap Image.jpg"
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new DocumentFormat.OpenXml.Drawing.Blip(
                                             new DocumentFormat.OpenXml.Drawing.BlipExtensionList(
                                                 new DocumentFormat.OpenXml.Drawing.BlipExtension()
                                                 {
                                                     Uri =
                                                       "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 })
                                         )
                                         {
                                             Embed = relationshipId,
                                             CompressionState =
                                             DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print
                                         },
                                         new DocumentFormat.OpenXml.Drawing.Stretch(
                                             new DocumentFormat.OpenXml.Drawing.FillRectangle())),
                                     new PIC.ShapeProperties(
                                         new DocumentFormat.OpenXml.Drawing.Transform2D(
                                             new DocumentFormat.OpenXml.Drawing.Offset() { X = 0L, Y = 0L },
                                             new DocumentFormat.OpenXml.Drawing.Extents() { Cx = cx, Cy = yx }), //与上面的对准
                                         new DocumentFormat.OpenXml.Drawing.PresetGeometry(
                                             new DocumentFormat.OpenXml.Drawing.AdjustValueList()
                                         )
                                         { Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle }))
                             )
                             { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                     )
                     {
                         DistanceFromTop = (UInt32Value)0U,
                         DistanceFromBottom = (UInt32Value)0U,
                         DistanceFromLeft = (UInt32Value)0U,
                         DistanceFromRight = (UInt32Value)0U,
                         EditId = "50D07946"
                     });

            paragraph.Append(new Run(element));
            // Append the reference to body, the element should be in a Run.
            // body.AppendChild(new Paragraph(new Run(element)));
        }

        /// <summary>
        /// 插入图片,默认宽度和默认高度
        /// </summary>
        /// <param name="tableCell"></param>
        /// <param name="relationshipId"></param>
        public static void AddImageToTableCell(TableCell tableCell, string relationshipId)
        {
            // Define the reference of the image.
            var element =
                 new Drawing(
                     new DW.Inline(
                         new DW.Extent() { Cx = 990000L, Cy = 792000L }, // 调节图片大小
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = "Picture1",
                             Title = "投标图片"
                         },
                         new DW.NonVisualGraphicFrameDrawingProperties(
                             new DocumentFormat.OpenXml.Drawing.GraphicFrameLocks() { NoChangeAspect = true }),
                         new DocumentFormat.OpenXml.Drawing.Graphic(
                             new DocumentFormat.OpenXml.Drawing.GraphicData(
                                 new PIC.Picture(
                                     new PIC.NonVisualPictureProperties(
                                         new PIC.NonVisualDrawingProperties()
                                         {
                                             Id = (UInt32Value)0U,
                                             Name = "New Bitmap Image.jpg"
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new DocumentFormat.OpenXml.Drawing.Blip(
                                             new DocumentFormat.OpenXml.Drawing.BlipExtensionList(
                                                 new DocumentFormat.OpenXml.Drawing.BlipExtension()
                                                 {
                                                     Uri =
                                                       "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 })
                                         )
                                         {
                                             Embed = relationshipId,
                                             CompressionState =
                                             DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print
                                         },
                                         new DocumentFormat.OpenXml.Drawing.Stretch(
                                             new DocumentFormat.OpenXml.Drawing.FillRectangle())),
                                     new PIC.ShapeProperties(
                                         new DocumentFormat.OpenXml.Drawing.Transform2D(
                                             new DocumentFormat.OpenXml.Drawing.Offset() { X = 0L, Y = 0L },
                                             new DocumentFormat.OpenXml.Drawing.Extents() { Cx = 990000L, Cy = 792000L }), //与上面的对准
                                         new DocumentFormat.OpenXml.Drawing.PresetGeometry(
                                             new DocumentFormat.OpenXml.Drawing.AdjustValueList()
                                         )
                                         { Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle }))
                             )
                             { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
                     )
                     {
                         DistanceFromTop = (UInt32Value)0U,
                         DistanceFromBottom = (UInt32Value)0U,
                         DistanceFromLeft = (UInt32Value)0U,
                         DistanceFromRight = (UInt32Value)0U,
                         EditId = "50D07946"
                     });
            // Append the reference to body, the element should be in a Run.
            tableCell.AppendChild(new Paragraph(new Run(element)));
        }

        ///// <summary>
        ///// 插入图片,指定宽度和默认高度
        ///// </summary>
        ///// <param name="body"></param>
        ///// <param name="relationshipId"></param>
        ///// <param name="imgWidth">图片在word显示的宽度（单位：cm）,默认5.93cm</param>
        ///// <param name="imgHeight">图片在word显示的高度（单位：cm），默认10.2cm</param>
        //public static void AddImageToBody(DocumentFormat.OpenXml.Wordprocessing.Body body, string relationshipId, long imgWidth, long imgHeight)
        //{
        //    //Open xml中的度量单位为EMU（全称为 English Metric Unit)，1cm = 360000EMUS,所以7.935cm = 7.935 * 360000 = 2857500
        //    long cx = imgWidth * 360000;
        //    long yx = imgHeight * 360000;
        //    // Define the reference of the image.
        //    var element =
        //         new Drawing(
        //             new DW.Inline(
        //                 new DW.Extent() { Cx = cx, Cy = yx }, // 调节图片大小,如new DW.Extent() { Cx = 990000L, Cy = 792000L }
        //                 new DW.EffectExtent()
        //                 {
        //                     LeftEdge = 0L,
        //                     TopEdge = 0L,
        //                     RightEdge = 0L,
        //                     BottomEdge = 0L
        //                 },
        //                 new DW.DocProperties()
        //                 {
        //                     Id = (UInt32Value)1U,
        //                     Name = "Picture_1",
        //                     Title = "图片"
        //                 },
        //                 new DW.NonVisualGraphicFrameDrawingProperties(
        //                     new DocumentFormat.OpenXml.Drawing.GraphicFrameLocks() { NoChangeAspect = true }),
        //                 new DocumentFormat.OpenXml.Drawing.Graphic(
        //                     new DocumentFormat.OpenXml.Drawing.GraphicData(
        //                         new PIC.Picture(
        //                             new PIC.NonVisualPictureProperties(
        //                                 new PIC.NonVisualDrawingProperties()
        //                                 {
        //                                     Id = (UInt32Value)0U,
        //                                     Name = "New Bitmap Image.jpg"
        //                                 },
        //                                 new PIC.NonVisualPictureDrawingProperties()),
        //                             new PIC.BlipFill(
        //                                 new DocumentFormat.OpenXml.Drawing.Blip(
        //                                     new DocumentFormat.OpenXml.Drawing.BlipExtensionList(
        //                                         new DocumentFormat.OpenXml.Drawing.BlipExtension()
        //                                         {
        //                                             Uri =
        //                                               "{28A0092B-C50C-407E-A947-70E740481C1C}"
        //                                         })
        //                                 )
        //                                 {
        //                                     Embed = relationshipId,
        //                                     CompressionState =
        //                                     DocumentFormat.OpenXml.Drawing.BlipCompressionValues.Print
        //                                 },
        //                                 new DocumentFormat.OpenXml.Drawing.Stretch(
        //                                     new DocumentFormat.OpenXml.Drawing.FillRectangle())),
        //                             new PIC.ShapeProperties(
        //                                 new DocumentFormat.OpenXml.Drawing.Transform2D(
        //                                     new DocumentFormat.OpenXml.Drawing.Offset() { X = 0L, Y = 0L },
        //                                     new DocumentFormat.OpenXml.Drawing.Extents() { Cx = 990000L, Cy = 792000L }), //与上面的对准
        //                                 new DocumentFormat.OpenXml.Drawing.PresetGeometry(
        //                                     new DocumentFormat.OpenXml.Drawing.AdjustValueList()
        //                                 )
        //                                 { Preset = DocumentFormat.OpenXml.Drawing.ShapeTypeValues.Rectangle }))
        //                     )
        //                     { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
        //             )
        //             {
        //                 DistanceFromTop = (UInt32Value)0U,
        //                 DistanceFromBottom = (UInt32Value)0U,
        //                 DistanceFromLeft = (UInt32Value)0U,
        //                 DistanceFromRight = (UInt32Value)0U,
        //                 EditId = "50D07946"
        //             });
        //    // Append the reference to body, the element should be in a Run.
        //    body.AppendChild(new Paragraph(new Run(element)));
        //}

        /// <summary>
        /// 通过body的元素返回图片数据流
        /// </summary>
        /// <param name="openXmlElement">源文件的body元素</param>
        /// <param name="mainPart">源文件MainDocumentPart元素</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Stream GetStreamByopenXmlElementDrawing(OpenXmlElement openXmlElement, MainDocumentPart mainPart, ref long width, ref long height)
        {

            Drawing drawing = openXmlElement as Drawing;
            //得到图像的内嵌ID（外嵌没做处理）
            var inline = drawing.Inline;
            var extent = inline.Extent;
            string imgTitle = inline.DocProperties.Title;
            width = extent.Cx.Value;
            height = extent.Cy.Value;
            var pic = inline.Graphic.GraphicData.GetFirstChild<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
            if (pic == null)
            {
                var embed = pic.BlipFill.Blip.Embed.Value;
                //得到图像流

                var part = mainPart.GetPartById(embed);
                var stream = part.GetStream();
                ////流转2进制，本来想返回二进制,考虑到还要转换，所以这里直接返回流
                //byte[] bytes = new byte[stream.Length];
                //stream.Read(bytes, 0, bytes.Length);
                return stream;
            }
            else
            {
                return null;
            }
        }
        //private static string GetTuXing(OpenXmlElement openXmlElement)
        //{
        //    var a = openXmlElement as AlternateContent;

        //}
        public static List<string> GetRelationShipIdListByopenXmlElement(OpenXmlElement openXmlElement, MainDocumentPart mainPart)
        {
            List<string> list = new List<string>();
            try
            {
                var picList = openXmlElement.Descendants<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
                if (picList != null && picList.Count() > 0)
                {
                    foreach (var itemPic in picList)
                    {
                        if (itemPic != null)
                        {
                            string embed = itemPic.BlipFill.Blip.Embed.Value;
                            list.Add(embed);
                           
                        }
                        else
                        {
                         
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("出现异常：" + ex.Message);
                //LogTools.WriteLine("读取图片XML异常：" + openXmlElement.InnerXml, "读取xml图片失败");
            }
            return list;

        }


        public static List<string> GetRelationShipIdListByopenXmlElementDrawing(OpenXmlElement openXmlElement, MainDocumentPart mainPart)
        {
            List<string> list = new List<string>();
            if (openXmlElement is Drawing)
            {
                try
                {
                    Drawing drawing = openXmlElement as Drawing;

                    var picList = drawing.Descendants<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
                    foreach (var itemPic in picList)
                    {
                        if (itemPic != null)
                        {
                            string embed = itemPic.BlipFill.Blip.Embed.Value;
                            list.Add(embed);
                          
                        }
                        else
                        {
                            //日志
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("出现异常：" + ex.Message);
                   
                }
            }
            return list;

        }


        public static string GetRelationShipIdByopenXmlElementDrawing(OpenXmlElement openXmlElement, MainDocumentPart mainPart)
        {

            string embed = "";
            try
            {
                Drawing drawing = openXmlElement as Drawing;
                //得到图像的内嵌ID（外嵌没做处理）
                var inline = drawing.Inline;
                if (inline != null)
                {
                    var pic = inline.Graphic.GraphicData.GetFirstChild<DocumentFormat.OpenXml.Drawing.Pictures.Picture>();
                    if (pic != null)
                    {
                        embed = pic.BlipFill.Blip.Embed.Value;
                      //  LogTools.WriteLine("读取图片XML成功：" + openXmlElement.InnerXml, "读取xml图片成功");
                    }
                    else
                    {
                       // LogTools.WriteLine("读取图片为空：" + openXmlElement.OuterXml, "读取xml图片为空");
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("出现异常：" + ex.Message);

            }
            return embed;

        }
        /// <summary>
        /// 返回源word中图片Uri
        /// 返回示例
        /// /media/image.jpg
        ///media/image2.jpg
        ///media/image3.jpg
        ///media/image4.jpg
        ///media/image5.jpg
        ///media/image6.jpg
        ///media/image7.jpg
        ///media/image8.jpg
        ///media/image9.jpg
        ///media/image10.jpg
        /// </summary>
        /// <param name="mainPart"></param>
        /// <returns></returns>
        public static List<Uri> GetFileUriList(MainDocumentPart mainPart)
        {
            //  Uri partUri = new Uri("/media/image.jpg", UriKind.Relative);
            IEnumerable<ImagePart> imagePartList = mainPart.ImageParts;
            var list = (from item in imagePartList select item.Uri).ToList();
            return list;
        }
        #region 操作多媒体类型

        /// <summary>
        /// 图片从源文件添加到目标文件中
        /// </summary>
        /// <param name="relationShipIdList"></param>
        /// <param name="mainDocumentPart">源主文档</param>
        /// <param name="destPackage">目标Package</param>
        /// <param name="imagePartList">源文件的图片部件</param>
        public static void InsertImgSourceToDest(List<string> relationShipIdList, MainDocumentPart mainDocumentPart, Package destPackage, IEnumerable<ImagePart> imagePartList)
        {
            string contenType = "image/bmp";
            foreach (var tempRelationShip in relationShipIdList)
            {
                foreach (var item in imagePartList)
                {
                    string imgRelationShipId = mainDocumentPart.GetIdOfPart(item);
                    string temprelationShipId = relationShipIdList.Find(x => x == imgRelationShipId);
                    if (!string.IsNullOrEmpty(temprelationShipId))
                    {
                        FileInfo fi = new FileInfo(item.Uri.ToString());
                        Uri imageUri = new Uri("/word/media/" + fi.Name, UriKind.Relative);//如果使用相对路径需要自定义Relation关系
                        XmlToImg.CreateNewPart(imageUri, item.ContentType, item.GetStream(), imgRelationShipId, destPackage);
                    }
                }
            }
        }
        /// <summary>
        /// 将图片从源word的压缩包中移动到目标word的压缩包中
        /// </summary>
        /// <param name="imageUri"></param>
        /// <param name="contentType"></param>
        /// <param name="imgStream">源word中的图片流</param>
        /// <param name="relationId">document.xml和document.xml.rels的关联ID,即document.xml中的Embed</param>
        /// <param name="destPackage"></param>
        /// <returns></returns>
        public static System.IO.Packaging.PackagePart CreateNewPart(Uri imageUri, string contentType, Stream imgStream, string relationId, Package destPackage)
        {
            if (destPackage.PartExists(imageUri))
                return destPackage.GetPart(imageUri);
            //FileInfo fi = new FileInfo(imageUrl);
            // Uri imageUri = new Uri("/word/media/" + fi.Name, UriKind.Relative);
            System.IO.Packaging.PackagePart newPart = destPackage.CreatePart(imageUri, contentType, System.IO.Packaging.CompressionOption.Normal);
            //FileStream ifs = new FileStream(imageUrl, FileMode.Open, FileAccess.Read);
            using (Stream partStream =
                newPart.GetStream(FileMode.Create, FileAccess.Write))
            {
                byte[] byteTmp = new byte[1024];
                int count = 0;
                while ((count = imgStream.Read(byteTmp, 0, 1024)) > 0)
                {
                    partStream.Write(byteTmp, 0, count);
                }
            }
            string ImgNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
            Uri docmentUri = new Uri(@"/word/document.xml", UriKind.Relative);
            PackageRelationship relationship = PackageHelper.CreateInternalRelationship(docmentUri, imageUri, ImgNamespace, relationId, destPackage);
            // Console.WriteLine(relationship.Id);

            return newPart;
        }
        #endregion

    }
}
